<?php

namespace app\user\controller\mall\order;

use app\user\controller\mall\Base;
use think\Db;
use think\Exception;
use app\common\model\mall\oper\Msgtpl;
use app\common\model\mall\oper\Notification;
use addons\mall\library\Service;
use think\Hook;

/**
 * 买家定单
 *
 * @icon fa fa-circle-o
 */
class Myorder extends Base{

    /**
     * Orders模型对象
     * @var \app\common\model\mall\order\Order
     */
    protected $model = null;

    /**
     * 无需登录的方法,同时也就不需要鉴权了
     * @var array
     */
    protected $noNeedLogin = [];

    /**
     * 无需鉴权的方法,但需要登录
     * @var array
     */
    protected $noNeedRight = [];

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\common\model\mall\order\Order;
        $this->view->assign("delivertypeList", $this->model->getDelivertypeList());
        $this->view->assign("paytypeList", $this->model->getPaytypeList());
        $this->view->assign("ordersrcList", $this->model->getOrdersrcList());
        $this->view->assign("promTypeList", $this->model->getPromTypeList());
        $this->view->assign("statusList", $this->model->getStatusList());

    }

    /**
     * 获取用户订单列表
     */
    public function index()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams(null,true,"o");

            $total = $this->model->alias('o')
                ->join('__MALL_SHOP_SHOP__ s','o.shop_id=s.id','left')
                ->join('__MALL_ORDER_COMPLAIN__ oc','o.id=oc.order_id','left')
                ->join('__MALL_ORDER_REFUND__ orf','o.id=orf.order_id','left')
                ->field('o.id,o.id order_id,o.shop_id,o.express_id,o.expressNo,o.orderRemarks,o.noticeDeliver,o.orderunique,o.orderNo,
                    o.goodsMoney,o.totalMoney,o.realTotalMoney,o.deliverType,o.deliverMoney,
		            o.payis,o.payType,o.payFrom,o.needPay,o.appraiseis,o.refundis,o.orderSrc,o.prom_type,
		            o.createtime,o.useScore,oc.id complainId,o.orderCode,o.status,orf.id refundId,s.name,s.shopQQ,s.shopWangWang')
                ->where('o.user_id',$this->auth->id)
                ->where($where)->order($sort, $order)->count();

            $list = $this->model->alias('o')
                ->join('__MALL_SHOP_SHOP__ s','o.shop_id=s.id','left')
                ->join('__MALL_ORDER_COMPLAIN__ oc','o.id=oc.order_id','left')
                ->join('__MALL_ORDER_REFUND__ orf','o.id=orf.order_id','left')
                ->field('o.id,o.id order_id,o.shop_id,o.express_id,o.expressNo,o.orderRemarks,o.noticeDeliver,o.orderunique,o.orderNo,
                    o.goodsMoney,o.totalMoney,o.realTotalMoney,o.deliverType,o.deliverMoney,
		            o.payis,o.payType,o.payFrom,o.needPay,o.appraiseis,o.refundis,o.orderSrc,o.prom_type,
		            o.createtime,o.useScore,oc.id complainId,o.orderCode,o.status,orf.id refundId,s.name,s.shopQQ,s.shopWangWang')
                ->where('o.user_id',$this->auth->id)
                ->where($where)->order($sort, $order)->limit($offset, $limit)->select();

            if(count($list)>0){
                $order_ids = [];
                foreach ($list as $v){
                    $order_ids[] = $v['order_id'];
                }
                $goods = db('mall_order_goods')->where('order_id','in',$order_ids)->select();
                $goodsMap = [];
                foreach ($goods as $v){
                    $v['goodsSpecNames'] = str_replace('@@_@@','、',$v['goodsSpecNames']);
                    $goodsMap[$v['order_id']][] = $v;
                }
                foreach ($list as $key => $v){
                    $list[$key]['allowRefund'] = 0;
                    //只要是在线支付取消和拒收，且没有退款的，才可以申请退款
                    if($v['payType']==1 && $v['refundis']==0 && $v['refundId']=='' && (($v['payis'] ==1 || $v['useScore']>0) && in_array($v['status'],["canceled","rejected"]))){
                        $list[$key]['allowRefund'] = 1;
                    }
                    //货到付款中使用了积分支付，且没有退款的的，也可以申请退款
                    if($v['payType']==0 && $v['refundis']==0 && $v['refundId']=='' && $v['useScore']>0){
                        $list[$key]['allowRefund'] = 1;
                    }
                    $list[$key]['list'] = $goodsMap[$v['order_id']];
                    //未投诉，且在线支付待发货、待收货、待评价、已完成的定单，可进行投诉
                    if($v['complainId']=="" && ($v['payType']==1 && in_array($v['status'],["undeliver","unreceive","unappraise","finished"]))){
                        $list[$key]['isComplain'] = 1;
                    }

                }
            }

            $result = array("total" => $total, "rows" => $list);

            return json($result);
        }
        return $this->view->fetch();

    }

    /**
     * 用户-提醒发货
     */
    public function notice($ids = null){
        $row = $this->model->field('shop_id,orderNo,noticeDeliver')
            ->where( 'id' , $ids)->find();
        if (!$row) $this->error(__('No Results were found'));
        if ($this->request->isAjax()) {
            Db::startTrans();
            try {
                $result = $row->allowField(true)->save(['noticeDeliver'=> 1]);
                if ($result !== false) {

                    //发送消息提醒卖家
                    $to_user_id = \app\common\model\mall\shop\Shop::getFieldById($row['shop_id'],"user_id");
                    $to = \app\common\model\mall\shop\Extra::where("shop_id",$row['shop_id'])
                        ->field("applyLinkTel,applyLinkEmail")->find();
                    $find = ['${LOGIN_NAME}', '${ORDER_NO}'];
                    $replace = [$this->auth->nickname?$this->auth->nickname:$this->auth->username, $row['orderNo']];
                    $content = Msgtpl::getMsgByTpl('ORDER_REMINDER', $find, $replace);
                    if ($content != '') {
                        Notification::record("发货提醒", $content, $this->actionname, $this->controllername, $ids, $to_user_id);
                        $template_id = 1;
                        Hook::listen('vbot_send_msg', $template_id, [
                            'content'         => $content,
                            'at_mobiles'     => $to["applyLinkTel"],
                            'is_atall'       => 0,
                        ]);
                    }

                    Db::commit();
                    $this->success();
                } else {
                    Db::rollback();
                    $this->error($row->getError());
                }
            } catch (\think\exception\PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
        }
    }

    /**
     * 用户取消订单
     */
    public function cancel($ids = null){
        $row = $this->model->where('id',$ids)
            ->field('id,shop_id,orderNo,cancelReason,orderCode,payis,orderType,payType,status,
                goodsMoney,deliverMoney,useScore,scoreMoney,totalMoney,realTotalMoney')
            ->find();
        if (!$row) $this->error(__('No Results were found'));
        $userIds = $this->getDataLimitUserIds();
        if (is_array($userIds)) {
            if (!in_array($row[$this->dataLimitField], $userIds)) {
                $this->error(__('You have no permission'));
            }
        }
        hook('beforeCancelOrder',['id'=>$ids]);
        if ($this->request->isPost()) {
            $params = $this->request->post("row/a");
            if ($params) {
                Db::startTrans();
                try {
                    //是否采用模型验证
                    if ($this->modelValidate) {
                        $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                        $validate = $this->modelSceneValidate ? $name . '.edit' : $name;
                        $result = $this->validate($params,$validate);
                        if(true !== $result){
                            // 验证失败 输出错误信息
                            $this->error($result);
                        }
                    }

                    $params["status"] = "canceled";
                    //如为到付，或线上未付，则把应付金额设置为0
                    if($row['payType']==0 || ($row['payType']==1 && $row['payis']==0))
                        $params['realTotalMoney'] = 0;
                    $result = $row->allowField(true)->save($params);

                    if ($result !== false) {
                        //正常订单商品库存处理
                        $goods = Db::name('mall_order_goods')->alias('og')
                            ->join('__MALL_GOODS_GOODS__ g','og.goods_id=g.id','inner')
                            ->where('og.order_id',$ids)->field('og.*,g.specis')->select();
                        //返还商品库存
                        foreach ($goods as $key => $v){
                            if($v['goodsType']==1){
                                //处理虚拟产品
                                $extraJson = json_decode($v['extraJson'],true);
                                foreach ($extraJson as  $ecard) {
                                    Db::name('mall_goods_virtual')->where('id',$ecard['cardId'])
                                        ->update(['order_id'=>0,'orderNo'=>'','useis'=>0]);
                                }
                                $counts = Db::name('mall_goods_virtual')->where(['status'=>'normal','goods_id'=>$v['goods_id'],'useis'=>0])->count();
                                Db::name('mall_goods_goods')->where('id',$v['goods_id'])->setField('goodsstock',$counts);
                            }else{
                                //处理实物产品
                                if($row['orderCode']=='order'){
                                    //修改库存
                                    if($v['specis']>0){
                                        Db::name('mall_goods_salespec')->where('id',$v['goodsspec_id'])->setInc('specstock',$v['goodsNum']);
                                    }
                                    Db::name('mall_goods_goods')->where('id',$v['goods_id'])->setInc('goodsstock',$v['goodsNum']);
                                }
                            }
                        }
                        //提交订单后执行钩子
                        hook('afterCancelOrder',['order_id'=>$ids]);

                        //发送平台短信给管理员
                        $find = ['${ORDER_NO}'];
                        $replace = [$row['orderNo']];
                        $content = Msgtpl::getMsgByTpl('PHONE_ADMIN_CANCEL_ORDER', $find, $replace);
                        if ($content != '') {
                            Service::smsAdminNotice($content,'orderfailure');
                        }

                        Db::commit();
                        $this->success();
                    } else {
                        Db::rollback();
                        $this->error($row->getError());
                    }
                } catch (\think\exception\PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $this->view->assign("cancelreasonList", $this->model->getCancelreasonList());
        $this->view->assign("row", $row);
        return $this->view->fetch();
    }

    /**
     * 用户收货[同时给外部虚拟商品收货调用]
     */
    public function receive($ids = null){
        //$ids = $ids?$ids:$this->request->param("ids");
        $row = $this->model->where('id',$ids)
            ->field('id,shop_id,orderNo,cancelReason,orderCode,payis,orderType,payType,status,
                goodsMoney,deliverMoney,useScore,scoreMoney,totalMoney,realTotalMoney,orderScore,commissionFee')
            ->find();
        if (!$row) $this->error(__('No Results were found'));

        if ($this->request->isAjax()) {
            Db::startTrans();
            try {
                $params = [];
                $params["status"] = "unappraise";
                $params['receiveTime'] = date('Y-m-d H:i:s');
                $result = $row->allowField(true)->save($params);

                if ($result !== false) {
                    //确认收货后执行钩子
                    hook('afterUserReceive',['id'=>$ids]);

                    if(config('mall.statementType')==1){
                        //修改商家未计算订单数
                        $prefix = config('database.prefix');
                        $upSql = 'update '.$prefix.'mall_shop_shop set noSettledOrderNum=noSettledOrderNum+1,noSettledOrderFee=noSettledOrderFee-'.$row['commissionFee'].' where id='.$row['shop_id'];
                        Db::execute($upSql);
                    }else{
                        //即时结算
                        model('Settlement','model\mall\shop')->speedySettlement($ids);
                    }

                    //给用户增加积分
                    if(config("site.isOrderScore")==1 && $row['orderScore']>0){
                        \app\common\model\User::score($row['orderScore'], $this->auth->id,"交易订单【".$row['orderNo']."】获得积分".$row['orderScore']."个");
                    }
                    Db::commit();
                    $this->success();
                } else {
                    Db::rollback();
                    $this->error($row->getError());
                }
            } catch (\think\exception\PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
        }
    }

    /**
     * 用户拒收订单
     */
    public function reject($ids = NULL){
        $row = $this->model->where("id",$ids)
            ->field('id,shop_id,orderNo,cancelReason,orderCode,payis,orderType,payType,status,
                goodsMoney,deliverMoney,useScore,scoreMoney,totalMoney,realTotalMoney,rejectReason,rejectOtherReason')
            ->find();
        if (!$row) $this->error(__('No Results were found'));
        $userIds = $this->getDataLimitUserIds();
        if (is_array($userIds)) {
            if (!in_array($row[$this->dataLimitField], $userIds)) {
                $this->error(__('You have no permission'));
            }
        }
        if($this->request->isPost()){
            $params = $this->request->post("row/a");
            if ($params) {
                Db::startTrans();
                try{
                    //是否采用模型验证
                    if ($this->modelValidate) {
                        $name = str_replace("\\model\\", "\\validate\\", get_class($this->model));
                        $validate = $this->modelSceneValidate ? $name . '.edit' : $name;
                        $result = $this->validate($params,$validate);
                        if(true !== $result){
                            // 验证失败 输出错误信息
                            $this->error($result);
                        }
                    }

                    $params["status"] = "rejected";
                    //如果是货到付款拒收的话，把实付金额设置为0
                    if($row['payType']==0) $params['realTotalMoney'] = 0;
                    $result = $row->allowField(true)->save($params);
                    if(false != $result){

                        //发送平台短信给管理员
                        $find = ['${ORDER_NO}'];
                        $replace = [$row['orderNo']];
                        $content = Msgtpl::getMsgByTpl('PHONE_ADMIN_REJECT_ORDER', $find, $replace);
                        if ($content != '') {
                            Service::smsAdminNotice($content,'orderfailure');
                        }

                        Db::commit();
                        $this->success();
                    }else {
                        Db::rollback();
                        $this->error($row->getError());
                    }
                } catch (\think\exception\PDOException $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                } catch (Exception $e) {
                    Db::rollback();
                    $this->error($e->getMessage());
                }
            }
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $this->view->assign("rejectreasonList", $this->model->getRejectreasonList());
        $this->view->assign("row", $row);
        return $this->view->fetch();
    }

    /**
     * 根据订单id获取 商品信息跟商品评价
     */
    public function appraise($ids = NULL){

        //获取订单中的商品信息
        $goodsInfo = Db::name('mall_order_goods')->alias('g')
            ->join('__MALL_ORDER_ORDER__ o','g.order_id = o.id','LEFT')
            ->field('g.id,o.shop_id,g.order_id,g.goods_id,g.salespec_id')
            ->where(['g.order_id'=>$ids])
            ->select();
        //根据商品id 与 订单id 取评价
        $alreadys = 0;// 已评价商品数
        $count = count($goodsInfo);//订单下总商品数
        if($count>0){
            //循环处理订单中的商品
            $a_ids = [];
            $result = true;
            Db::startTrans();
            try{
                foreach($goodsInfo as $k=>$v){
                    //规格属性名称
                    //$goodsInfo[$k]['goodsSpecNames'] = $v['goodsSpecNames'];
                    //查找订单中商品的评价记录
                    $appraise = Db::name('mall_goods_appraise')
                        ->field('goodsraty,serviceraty,timeraty,content,receivimg,createtime')
                        ->where(['goods_id'=>$v['goods_id'],
                            'goodsspec_id'=>$v['salespec_id'],
                            'order_id'=>$ids,
                            'shop_id'=>$v['shop_id'],
                            'user_id'=>$this->auth->id,
                            'ordergoods_id'=>$v['id'],
                        ])->find();
                    //找到则为已评
                    if(!empty($appraise)){
                        ++$alreadys;
                        $appraise['images'] = ($appraise['images']!='')?explode(',', $appraise['images']):[];
                    }
                    else{//未找到则新增评价关联数据
                        $newappraise = new \app\common\model\mall\goods\Appraise;
                        $newdata=[
                            'shop_id'=>$v['shop_id'],
                            'order_id'=>$ids,
                            'ordergoods_id'=>$v['id'],
                            'goods_id'=>$v['goods_id'],
                            'goodsspec_id'=>$v['salespec_id'],
                            'user_id'=>$this->auth->id,
                            'content'=>"",
                        ];
                        $res = $newappraise->isUpdate(false)->save($newdata);
                        $result = $res && $result;
                        $a_ids[] = $newappraise->id;

                    }

                }

                if( $result != false && !empty($a_ids)){
                    //修改订单状态至完成
                    //$this->model->where("id",$ids)->setField("status","finished");
                    Db::commit();
                    $this->success("有".count($a_ids)."条商品需要评价！",'/user/mall/goods/myappraise/edit', $a_ids);
                }
                else{
                    Db::rollback();
                    $this->error("目前没有新增待评价商品，请移步至【我的评价】继续完成评价",'/user/mall/goods/myappraise/index');
                }
            } catch (\think\exception\PDOException $e) {
                Db::rollback();
                $this->error($e->getMessage());
            } catch (Exception $e) {
                Db::rollback();
                $this->error($e->getMessage());
            }
        }else{
            $this->error(__('No Results were found'));
        }
    }
}
